#include "glwidget.h"

GLWidget::GLWidget(QWidget *parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) {
	elapsed = 0;
	setMinimumSize(640, 480);
	setAutoFillBackground(false);

	background = QBrush(QColor(255, 255, 255));
	arrowColor = QColor(255, 0, 0);
	arrowPen = QPen(arrowColor);
	arrowPen.setWidth(1);

	double omega = 0.3;
	vec<int> gridDim = {64, 32};
	lbm = LBM(gridDim, omega);
	lbm.initialize(1.0);
	lbm.putRectangleObstacle(16,11,1,10);

	uMax = lbm.getUMax();
}

void GLWidget::drawArrow(QPainter *painter, QPoint p0, QPointF scale, double angle) {
	painter->setPen(arrowPen);
	painter->save();
	painter->translate(p0);
	painter->rotate(-angle);
	painter->scale(scale.x(), scale.y());
	painter->drawLine(0, 0, 10, 0);
	painter->drawLine(10, 0, 7, -3);
	painter->drawLine(10, 0, 7, 3);
	painter->restore();
}

void GLWidget::paint(QPainter *painter, QPaintEvent *event, int elapsed) {
	const double toDegrees = 180.0 / (4 * atan(1.0));
	painter->fillRect(event->rect(), background);

	vec<double> flechaMax;
	flechaMax.x = ((double)size().width()/lbm.getDim().x);
	flechaMax.y = ((double)size().height()/lbm.getDim().y);
	toPixels = sqrt(pow(flechaMax.x,2) + pow(flechaMax.y,2))/(sqrt(2.0)*uMax);

	double dx = flechaMax.x;
	double dy = flechaMax.y;

	for (int i = 0; i < lbm.getDim().x; i++)
		for (int j = 0; j < lbm.getDim().y; j++) {
			vec<double> _u = lbm.grid[i][j].u();
			double uMag = sqrt(pow(_u.x,2) + pow(_u.y,2));
			QPointF scale(uMag*toPixels/10, uMag*toPixels/12);
			double angle = atan2(_u.y, _u.x) * toDegrees;
			if (lbm.grid[i][j].isObstacle == false)
				drawArrow(painter, QPoint(i*dx, j*dy), QPointF(scale), angle);
			else
				painter->fillRect(floor(i*dx), floor(j*dy), ceil(dx), ceil(dy), QColor(0, 0, 255));
		}
}

void GLWidget::animate() {
	elapsed = (elapsed + qobject_cast<QTimer*>(sender())->interval()) % 1000;

	lbm.stream_step();
	cout << lbm.norm() << endl;
	lbm.collide_step();
	lbm.applyForce();

	repaint();
}

void GLWidget::paintEvent(QPaintEvent *event) {
	QPainter painter;
	painter.begin(this);
	painter.setRenderHint(QPainter::Antialiasing);
	paint(&painter, event, elapsed);
	painter.end();
}
